
//These are the classes for during game

function RiverObject()
{
	this.ico = null;
}

function BonusObject()
{
	this.prototype = RiverObject.prototype;
	this.ico = GUI.images.bonusImage;
	this.bonusAmount = 100;
}

function HealObject()
{
	this.ico = GUI.images.healImage;
	this.healAmount = 5;
}

function BlockingObject()
{
	this.prototype = RiverObject.prototype;
	this.ico = GUI.images.blockImage;
}

function JumpObject()
{
	this.prototype = RiverObject.prototype;
	this.ico =  GUI.images.jumpImage;
}

function Location(a,b)
{
	this.x = a;
	this.y = b;
	
	this.setLocation = function(a,b){
	if (a<100)
		this.x = 100;
	else
		if (a>600)
			this.x = 600;
		else
			this.x = a;
	if (b<0)
		this.y = 0;
	else
		if (b>440)
			this.y = 440;
		else
			this.y = b;
	}
}

function AreaController()
{
	this.checkIntersection = function() {
		var ulx = Math.floor((mygame.boat.location.x-100)/50);
		var uly = Math.floor((mygame.boat.location.y)/44);
		var densities = ({L:0,R:0,U:0,D:0})
		densities.L = (50-(mygame.boat.location.x%50))*2
		densities.R = (mygame.boat.location.x%50)*2
		
		densities.U = (44-(mygame.boat.location.y%44))*100/44
		densities.D = (mygame.boat.location.y%44)*100/44
		
		if (ulx==10)
			ulx = 9
		
		if (densities.R>60 && ulx<9)
			ulx++;
				
		if (!mygame.boat.jumped)
		{
			for(var iuly = uly;iuly<=uly+1;iuly++)
				for(var iulx = ulx;iulx<=ulx;iulx++)
				{
					var token = mygame.riverController.map.split(",")[iuly].charAt(iulx)+"";
					
					//if the a digit occours
					if (token==token.match(new RegExp("[0-9]+")))
					{
						//increase score
						mygame.sound.playGain();
						mygame.boat.score += parseInt(token.match(new RegExp("[0-9]+")))*100;
					}
					if (token=="+")
					{
						//increase health
						mygame.sound.playGain();
						mygame.boat.healed(15);
					}
					if (token=="#")
					{
						//decrease health
						mygame.sound.playStone();
						mygame.boat.damaged();
					}
					
					if (token=="_")
					{
						mygame.sound.playSplash();
						mygame.boat.jumped = true;
					}
					mygame.riverController.map = mygame.riverController.map.substr(0,iuly*11+iulx)+"."+mygame.riverController.map.substr(iuly*11+iulx+1);
				}
		}
	}
}

	
function Boat()
{
	this.prototype = RiverObject.prototype;
	this.speed = 10;
	this.HealthLevel = 3;
	this.HealthPercent = 100;
	this.ico = GUI.images.boatImage;
	this.score = 0;
	this.jumped = false;
	this.location = new Location(400,400);
	this.right = false;
	this.left = false;
	this.forward = false;
	this.back = false;
	this.rotdegree = 0;
	this.jumpTime = 0;
	
	this.moveRight = function(){
		if (this.right){
				this.location.setLocation(this.location.x+this.speed,this.location.y);
				this.rotdegree = (this.rotdegree+1)%90;
			}
	}
	this.moveLeft = function(){
		if (this.left){
			this.location.setLocation(this.location.x-this.speed,this.location.y);
			this.rotdegree = (this.rotdegree-1)%30;
		}
	}
	this.moveForward = function(){
		if (this.forward)
			this.location.setLocation(this.location.x,this.location.y-this.speed);
	}
	this.moveBack = function(){
		if (this.back)
			this.location.setLocation(this.location.x,this.location.y+this.speed);
	}
	
	this.renderBoat = function(){
		this.moveBack();
		this.moveForward();
		this.moveLeft();
		this.moveRight();
		mygame.areaController.checkIntersection();
		document.getElementById("status").innerHTML = this.jumped+" - "+Math.sin(this.jumpTime*Math.PI/180)*17
		if (this.jumped)
		{
			this.jumpTime = (this.jumpTime + 9) % 180;
			if (Math.sin(this.jumpTime*Math.PI/180)==0)
			{
				this.jumped = false;
				this.jumpTime = 0;
			}
		}
		//	context.rotate(this.rotdegree * Math.PI / 180);
		//	context.drawImage(this.ico, this.location.x*Math.cos(this.rotdegree*Math.PI/180)-this.location.y*Math.sin(this.rotdegree*Math.PI/180), -this.location.x*Math.sin(this.rotdegree*Math.PI/180)+this.location.y*Math.cos(this.rotdegree*Math.PI/180));
		//	context.rotate(-this.rotdegree * Math.PI / 180);
		context.drawImage(this.ico, this.location.x-Math.sin(this.jumpTime*Math.PI/180)*20,this.location.y-Math.sin(this.jumpTime*Math.PI/180)*34,50+Math.sin(this.jumpTime*Math.PI/180)*20,88+Math.sin(this.jumpTime*Math.PI/180)*34);
		
	}
	
	this.damaged = function(){
		if (this.HealthPercent>20)
		{
			this.HealthPercent -=20;
		}
		else
		{
			if (this.HealthLevel>0)
			{
				this.HealthLevel--;
				this.HealthPercent = 100;
			}
			else
			{
				this.HealthPercent =0;
				mygame.gameOver();
			}
			
		}
	
	}
	
	this.healed = function(hAmount){
		if (this.HealthPercent<100-hAmount)
		{
			this.HealthPercent +=hAmount;
		}
		else if(this.HealthPercent<100)
		{
			this.HealthPercent = 100;
		}
	}
	
	this.setKeyListeners = function(){
	
		
			canvas.onmousemove=function mm(e) {
				if (mygame.mouseControls)
				{
					var x = e.clientX-302-20;
					var y = e.clientY-92-44;
					if (x+15<mygame.boat.location.x){
						mygame.boat.left = true;
						mygame.boat.right = false;
						}
					if (x>mygame.boat.location.x+15){
						mygame.boat.right = true;
						mygame.boat.left = false;
						}
					if (y+15<mygame.boat.location.y){
						mygame.boat.forward = true;
						mygame.boat.back = false;
						}
					if (y>mygame.boat.location.y+15){
						mygame.boat.forward = false;
						mygame.boat.back = true;
						}
					if (y+15>mygame.boat.location.y && y<mygame.boat.location.y+15){
						mygame.boat.forward = false;
						mygame.boat.back = false;
					}
					if (x+15>mygame.boat.location.x && x<mygame.boat.location.x+15){
						mygame.boat.right = false;
						mygame.boat.left = false;
					}
				}
			}
		
		
		document.onkeydown = function(e) {
			switch (e.keyCode) {
				case 38: // up
					mygame.boat.forward = true;
					break;
				case 37: // left
					mygame.boat.left = true;
					break;
				case 39: // right
					mygame.boat.right = true;
					break;
				case 40: // down
					mygame.boat.back = true;
					break;
			}
		}

		document.onkeyup = function(e) {
			switch (e.keyCode) {
				case 38: // up
					mygame.boat.forward = false;
					break;
				case 37: // left
					mygame.boat.left = false;
					break;
				case 39: // right
					mygame.boat.right = false;
					break;
				case 40: // down
					mygame.boat.back = false;
					break;
			}
		}
	}
	
	this.setKeyListeners();
}

function Game()
{
	//Attributes
	this.timer = null;
	this.mouseControls = false;
	this.musicOn = true;
	this.gameSpeed = 60;
	this.level = 0;
	this.boat = new Boat();
	this.areaController = new AreaController();
	this.riverController = new RiverController();
	this.sound = new SoundManager();
	this.background = GUI.images.riverBackgroundImage;
	this.hicon =  GUI.images.healthIcon;
	
	if (options)
	{
		if (options.mouseControls)
			this.mouseControls = true;
		
		if (options.musicOn)
			this.musicOn = true;
	}
	
	//Methods
	this.start = function(){
		mygame.timer = setTimeout("mygame.updateTimer(0)",200);
	}
	
	this.changeDifficulty = function(newLevel){
		this.difficulty = newLevel;
	}
	
	this.setMusic = function(music){
		this.musicOn = music;
	}
	
	this.updateTimer = function(overflow){
		this.riverController.renderMap(overflow*2.2);
		this.boat.renderBoat();
		this.renderGamePanel();
		if ((mygame.level%10)==0)
		{
			mygame.level++;
			this.gameSpeed = this.gameSpeed * 0.9;
		}
		this.timer = setTimeout("mygame.updateTimer("+((overflow+1)%20)+")",this.gameSpeed);
	}
	
	
	this.renderGamePanel = function(){
		
		var height = 0;
		if (mygame.boat.location.y<300)
			height = 460;
		context.fillStyle = "rgba(0, 0, 0, 0.5)";  
		context.fillRect (0, height, 770, 50);
		context.fillStyle = "#FFF";  
		context.font = 'bold 22px Helvatica';
		context.fillText('SCORE: '+this.boat.score, 10, 30+height);
		context.fillText('LIFE: ', 160, 30+height);
		context.fillStyle = "rgba(250, 100, 100, 0.9)";  
		context.fillRect (230, 13+height, 400, 20);
		context.fillStyle = "rgba(50, 200, 100, 0.8)";  
		context.fillRect (230, 13+height, this.boat.HealthPercent*4, 20);	
		context.fillStyle = "#FFF";  
		context.fillText(this.boat.HealthLevel+' x ', 650, 30+height);
		context.drawImage(this.hicon, 690,0+height,30,50);
	}
	
	this.gameOver = function(){
		clearTimeout(this.timer);
		clearTimeout(mygame.timer);
		mygame.updateTimer = null;
		context.fillStyle = "rgba(0, 0, 0, 0.8)";  
		context.fillRect (0, 50, 770, 700);
		context.fillStyle = "#F00";  
		context.font = 'bold 40px Helvatica';
		context.fillText('GAME OVER!', 250, 80);
		var name = prompt("Please enter your name","");
		if (name!=null)
			GUI.scoreScreen.submitHighScore(name,mygame.boat.score,"TR",geoip_country_code());
		setTimeout("location.reload();",2000);
	}
}

function RiverController()
{
	//Attributes
	this.map = "";
	this.riverObjects = [new BonusObject(),new BlockingObject(),new JumpObject(),new HealObject()];

	//Methods
	this.initMap = function(){
		//Create a new Map
		if (this.map=="")
		{
			for(var i=0;i<=11;i++)
			{
				//this.map +=this.getRandomRow();
				//initially empty
				this.map +="..........";
				if (i<11)
					this.map += ",";
			}
		}
		//Delete Last Row
		this.map = this.map.substring(0, this.map.lastIndexOf(","));
		//Insert New Head Row
		this.map = this.getRandomRow()+","+this.map;
	};
	
	
	this.renderMap = function(overflow){
		if (overflow==0)
		{
			this.initMap();
			mygame.boat.score++;
			mygame.level++;
		}
		
		var context = canvas.getContext("2d");
		var mapRows = this.map.split(",");
		context.drawImage(mygame.background, 0, 0);
		for(var i=0;i<12;i++)
		{
			var currentRow = mapRows[i];
			for (var k = 0; k<10;k++)
			{
				//Block Object
				if (currentRow.charAt(k)+""=="#")
				{
					context.drawImage(mygame.riverController.riverObjects[1].ico, k*50+100, i*44+overflow,50,44);
				}
				//Heal Object
				else if(currentRow.charAt(k)+""=="+")
				{
					context.drawImage(mygame.riverController.riverObjects[3].ico, k*50+100, i*44+overflow,50,44);
				}
				//Jump Object
				else if (currentRow.charAt(k)+""=="_")
				{
					context.drawImage(mygame.riverController.riverObjects[2].ico, k*50+100, i*44+overflow,50,44);
				}
				//Bonus Object
				else if (currentRow.charAt(k)+""!=".")
				{
					context.drawImage(mygame.riverController.riverObjects[0].ico, k*50+100, i*44+overflow,50,44);
					//Write bonus amount on the background image
					context.fillStyle = "#232";  
					context.font = 'bold 18px Arial';
					context.fillText(parseInt(currentRow.charAt(k))*100, k*50+110, i*44+overflow+28);
				}
			}
			
		}
	}
	
	this.getRandomRow = function(){
		var myRow = "";
		for(var i=0;i<10;i++)
		{
			var myRand = Math.floor(Math.random()*22)
			
			if(myRand>14 && myRand<17)	//Block Object
			{
				myRow +="#";
			}
			else if(myRand==17)
			{
				myRow +="_";
			}
			else if(myRand==20 && mygame.boat.HealthPercent<100)	//Heal object
			{
				myRow +="+";
			}
			else if(myRand==21)	//Bonus object
			{
				//Reduces the chances for the higher point
				if (Math.floor(Math.random()*10)==9)
					myRow +=(Math.floor(Math.random()*9)+1)+"";
				else
					myRow +=(Math.floor(Math.random()*2)+1)+"";
			}
			else	//Water Object
			{
				myRow +=".";
			}
		}
		return myRow;
	}
}

function SoundManager()
{
	this.gain = [new Audio("gain.mp3"),new Audio("gain.mp3"),new Audio("gain.mp3")];
	this.stone = [new Audio("stone.mp3"),new Audio("stone.mp3"),new Audio("stone.mp3")];
	this.splash = [new Audio("splash.mp3"),new Audio("splash.mp3")];

	this.stoneCount = 0;
	this.gainCount = 0;
	this.splashCount = 0;
	
	
	this.playGain = function(){
		this.gainCount = (this.gainCount + 1) % 3;
		if (mygame.musicOn)
			this.gain[this.gainCount].play();
	}
	
	this.playStone = function(){
		this.stoneCount = (this.stoneCount + 1) % 3;
		if (mygame.musicOn)
			this.stone[this.stoneCount].play();
	}
	
	this.playSplash = function(){
		this.splashCount = (this.splashCount + 1) % 2;
		if (mygame.musicOn)
			this.splash[this.splashCount].play();
	}
}
